package com.pansoft.openplanet.util;

import android.content.Context;

import com.efounder.constant.EnvironmentVariable;
import com.efounder.utils.ResStringUtil;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.bean.Account;
import com.pansoft.openplanet.constant.IPAssetsConstant;
import com.pansoft.openplanet.db.AccountDao;
import com.utilcode.util.LogUtils;
import com.utilcode.util.ToastUtils;

import net.sf.json.JSONObject;

import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Bool;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.tx.Contract;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author : zzj
 * @e-mail : zhangzhijun@pansoft.com
 * @date : 2019/1/7 15:18
 * @desc :  虚拟商品转账的工具
 * @version: 1.0
 */
public class VirtualTransferUtils {
    private static final String TAG = "VirtualTransferUtils";
    public static final String BASE_VIRTUAL_PRODUCT_URL = EnvironmentVariable.getProperty("mallV2Url");
    private static VirtualTransferUtils instance = new VirtualTransferUtils();

    public static VirtualTransferUtils getInstance(){
        return instance;
    }

    private EthTokenTransactionManager transactionManager;
    private Account account;


    public  String getVirtualDataSignHex(String toAddress,String money,BigInteger nonce,String uuid, String goodId,String orderBh,
                                         String goodNum,String userId,
                                         Credentials credentials, BigInteger gasPrice, String contractAddress) {
        //交易签名
        String hexValue = null;
        //方法名 交易
        String methodName = "viewingTicket_transfer";
        //输入参数
        List<Type> inputParameters = new ArrayList<>();
        //转账地址
        Address toAddressValue = new Address(toAddress);
        //转账代币 金额
        Uint256 moneyValue = new Uint256(Convert.toWei(money, Convert.Unit.ETHER).toBigInteger());
        //uuid
        Uint256 uuidValue = new Uint256(new BigInteger(uuid));
        //商品编号
        Utf8String goodIdValue = new Utf8String(goodId);
        //订单编号
        Utf8String orderBhValue = new Utf8String(orderBh);
        //商品数量
        Uint256 goodNumValue = new Uint256(Long.valueOf(goodNum));
        //用户编号
        Utf8String userIdValue = new Utf8String(userId);
        inputParameters.add(toAddressValue);
        inputParameters.add(moneyValue);
        inputParameters.add(uuidValue);
        inputParameters.add(goodIdValue);
        inputParameters.add(orderBhValue);
        inputParameters.add(goodNumValue);
        inputParameters.add(userIdValue);
        //购买编号1
//        inputParameters.add(value);
        //购买编号2，现在默认为0
//        inputParameters.add(new Uint256(0L));
        //一个空集合
        List<TypeReference<?>> outputParameters = new ArrayList<>();
        TypeReference<Bool> typeReference = new TypeReference<Bool>() {
        };
        outputParameters.add(typeReference);

        //创建function
        Function function = new Function(methodName, inputParameters, outputParameters);
        //获取data
        String data = FunctionEncoder.encode(function);
        LogUtils.i("data:" + data);
        //创建原始交易
        RawTransaction transaction = RawTransaction.createTransaction(nonce, gasPrice, Contract.GAS_LIMIT, contractAddress, data);
        //签名Transaction，这里要对交易做签名
        byte[] signedMessage = null;
        signedMessage = TransactionEncoder.signMessage(transaction, credentials);
//        //这里我们拿到了交易的签名
        hexValue = Numeric.toHexString(signedMessage);
        return hexValue;
    }


    public void startVirtualProductTransaction(String toAddress,String money,BigInteger nonce,String uuid, String goodsId,String orderBh,
                                         String goodNum,String userId, Credentials credentials,
                                         BigInteger gasPrice, String contractAddress,
                                          final EthTokenTransactionManager.TransactionCallBack callBack) {
        String hexValue = getVirtualDataSignHex(toAddress, money, nonce, uuid,goodsId,orderBh,goodNum,userId, credentials, gasPrice, contractAddress);
        //接口调用参数
        HashMap<String, String> map = new HashMap<>();
        map.put("signature", hexValue);
        map.put("userId",userId);
        map.put("ordetBh",orderBh);
        //调用接口进行交易
        StarAssetRequestUtil.getRequest(TAG, BASE_VIRTUAL_PRODUCT_URL + "/pay/v3/contractDeal",
                map, new StarAssetRequestUtil.SARequestCallback() {
                    @Override
                    public void onSuccess(String response) {
                        try {
                            JSONObject jsonObject = JSONObject.fromObject(response);
                            LogUtils.i(jsonObject.toString());
                            JSONObject jsonObject1 = jsonObject.getJSONObject("data");
                            if (jsonObject1.containsKey("code") && jsonObject1.getInt("code") == 0) {
                                //交易成功，返回交易编号
                                callBack.transactionResult(true, response);

                            } else {
                                callBack.transactionResult(false, ResStringUtil.getString(R.string.open_planet_transaction_fail));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            callBack.transactionResult(false, ResStringUtil.getString(R.string.open_planet_transaction_fail));
                        }
                    }

                    @Override
                    public void onFail(String error) {
                        callBack.transactionResult(false, ResStringUtil.getString(R.string.open_planet_transaction_fail));
                    }
                });
    }

    public void startVirtualProductTransfer(Context mContext, final String fromAddress, final String toAddress, final String money, final String uuid, final String goodsId, final String orderBh,
                                            final String goodNum, final String userId, final String contractAddress, final String gasPrice1, final EthTokenTransactionManager.TransactionCallBack callBack) {

        transactionManager = new EthTokenTransactionManager(mContext);
        account = new AccountDao(mContext).getAccount(fromAddress);
        transactionManager.loadCredentialsASync(account,
                new EthTokenTransactionManager.LoadCredentialsCallBack() {
                    @Override
                    public void loadResult(boolean isSuccess, final Credentials credentials) {
                        if (!isSuccess) {
                            callBack.transactionResult(false, ResStringUtil.getString(R.string.open_planet_transaction_fail));
                            ToastUtils.showShort(ResStringUtil.getString(R.string.open_planet_transaction_fail));
                            return;
                        }
                        //2.获取nonce
                        LogUtils.i("获取nonce", credentials.getAddress());
                        transactionManager.getTransactionNonce(fromAddress, IPAssetsConstant.CHAIN_ID_TURBOCHAIN, new EthTokenTransactionManager.NonceCallBack() {
                            @Override
                            public void nonceResult(boolean isSuccess, BigInteger nonce) {
                                if (!isSuccess) {
                                    callBack.transactionResult(false, ResStringUtil.getString(R.string.open_planet_transaction_fail));
//                                    ToastUtils.showShort(ResStringUtil.getString(R.string.open_planet_transfer_fail));
                                    return;
                                }
                                //3.开始转账
//                                LogUtils.i("开始转账", nonce);
                                //智能合约转账
                                //矿工费
                                BigInteger gasPrice = Convert.toWei(gasPrice1, Convert.Unit.ETHER).toBigInteger().divide(Contract.GAS_LIMIT);
                                LogUtils.d("GAS:" + gasPrice.toString());
                                startVirtualProductTransaction(toAddress,money,nonce,uuid, goodsId,orderBh,goodNum,userId,
                                        credentials, gasPrice, contractAddress, new EthTokenTransactionManager.TransactionCallBack<String>() {
                                            @Override
                                            public void transactionResult(boolean isSuccess, String result) {
                                                if (!isSuccess) {
                                                    // showTransactionResult(false,ResStringUtil.getString(R.string.open_planet_transaction_fail));
                                                    callBack.transactionResult(false, ResStringUtil.getString(R.string.open_planet_transaction_fail));
                                                    // showTransactionResult(true, result);
                                                    return;
                                                }
                                                //转账成功
                                                callBack.transactionResult(true, result);
                                            }
                                        });
                            }
                        });
                    }
                });
    }
    /**
     *     关闭Observable，防止内存泄漏
     */


    public void closeTransaction() {
        if (transactionManager != null) {
            transactionManager.dispose();
            transactionManager = null;
        }
    }
}
